package com.ecommerce.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ecommerce.common.CommonEnum;
import com.ecommerce.common.ResultBody;
import com.ecommerce.entity.Coupon;
import com.ecommerce.entity.CouponReceive;
import com.ecommerce.entity.Order;
import com.ecommerce.entity.UserDetail;
import com.ecommerce.service.CouponReceiveService;
import com.ecommerce.service.CouponService;
import com.ecommerce.service.OrderService;
import com.ecommerce.service.UserDetailService;
import com.ecommerce.utils.WrapperUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * 订单Controller
 *
 * @author wang
 */
@RestController
@Api(value = "OrderController", tags = {"订单接口"})
@RequestMapping("/order")
@Log4j
public class OrderController {

    @Autowired
    private WrapperUtils wrapperUtils;

    @Autowired
    private OrderService orderService;

    @Autowired
    private CouponService couponService;

    @Autowired
    private UserDetailService userDetailService;

    @Autowired
    private CouponReceiveService couponReceiveService;


    /**
     * 查询订单列表
     *
     * @param order    订单
     * @param pageNum  页码
     * @param pageSize 条数
     * @return 订单列表
     */
    @ApiOperation(value = "查询订单列表", notes = "查询订单列表")
    @PostMapping(value = "/orderList")
    public ResultBody orderList(@RequestBody(required = false) Order order, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
        IPage<Order> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Order> wrapper = wrapperUtils.orderWrapper(order);
        wrapper.orderByDesc(Order::getCreateTime);
        return ResultBody.ok().data(orderService.page(page, wrapper));

    }

    @ApiOperation(value = "查询订单详情", notes = "查询订单详情")
    @PostMapping(value = "/orderDetail")
    public ResultBody orderDetail(@RequestBody Order order) {
        if (order.getOrderId() != null) {
            order = orderService.getById(order.getOrderId());
            if (order != null) {
                return ResultBody.ok().data(order);
            } else {
                return ResultBody.error().message("没有该订单");
            }
        }
        return ResultBody.error().message("没有该订单");
    }

    /**
     * 创建订单
     *
     * @param order 订单
     * @return 创建订单情况
     */
    @ApiOperation(value = "创建订单", notes = "创建订单")
    @PostMapping(value = "/createOrder")
    public ResultBody createOrder(@RequestBody Order order) {
        order.setOrderStatus(CommonEnum.WAIT_PAY.getCode());
        order.setCreateTime(new Date());
        boolean save = orderService.save(order);
        if (save) {
            return ResultBody.ok().data(order).message("创建订单成功");
        } else {
            return ResultBody.error().message("创建订单失败");
        }
    }

    /**
     * 支付订单
     *
     * @param order 订单
     * @return 支付订单情况
     */
    @ApiOperation(value = "支付订单", notes = "支付订单")
    @PostMapping(value = "/payOrder")
    public ResultBody payOrder(@RequestBody Order order) {
        Long orderId = order.getOrderId();
        if (orderId != null) {
            order = orderService.getById(orderId);
            if (order.getOrderStatus().equals(CommonEnum.WAIT_PAY.getCode())) {
                order.setOrderStatus(CommonEnum.WAIT_EXPRESS.getCode());
                order.setPayTime(new Date());
                useCoupon(order.getCouponId(), order);
                boolean save = orderService.updateById(order);
                if (save) {
                    return ResultBody.ok().message("支付订单成功");
                } else {
                    return ResultBody.error().message("支付订单失败");
                }
            } else {
                return ResultBody.error().message("支付订单失败");
            }
        }
        return ResultBody.error().message("没有该订单");
    }

    /**
     * 使用优惠券
     *
     * @param couponId 优惠券Id
     */
    private void useCoupon(Long couponId, Order order) {
        try {
            CouponReceive couponReceive = couponReceiveService.getById(couponId);
            Coupon coupon = couponService.getById(couponReceive.getCouponId());
            Date now = new Date();
            if (couponReceive.getStartTime().before(now) && couponReceive.getEndTime().after(now) && couponReceive.getStatus().equals(CommonEnum.UN_USED.getCode()) && coupon.getLimitAmount().compareTo(order.getReceivable()) >= -1) {
                couponReceive.setStatus(CommonEnum.USED.getCode());
                couponReceiveService.updateById(couponReceive);
                order.setPaidIn(order.getReceivable().subtract(coupon.getAmount()));
            } else {
                order.setPaidIn(order.getReceivable());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 订单发货
     *
     * @param order 订单
     * @return 订单发货情况
     */
    @ApiOperation(value = "订单发货", notes = "订单发货")
    @PostMapping(value = "/expressOrder")
    public ResultBody expressOrder(@RequestBody Order order) {
        Order originOrder = orderService.getById(order.getOrderId());
        if (originOrder.getOrderStatus().equals(CommonEnum.WAIT_EXPRESS.getCode())) {
            originOrder.setOrderStatus(CommonEnum.WAIT_CHECK.getCode());
            originOrder.setWaybillNo(order.getWaybillNo());
            originOrder.setExpressName(order.getExpressName());
            boolean save = orderService.updateById(originOrder);
            if (save) {
                return ResultBody.ok().message("订单发货成功");
            } else {
                return ResultBody.error().message("订单发货失败");
            }
        } else {
            return ResultBody.error().message("订单发货失败");
        }
    }

    /**
     * 订单签收
     *
     * @param order 订单
     * @return 订单签收情况
     */
    @ApiOperation(value = "订单签收", notes = "订单签收")
    @PostMapping(value = "/checkOrder")
    public ResultBody checkOrder(@RequestBody Order order) {
        Long orderId = order.getOrderId();
        if (orderId != null) {
            Order newOrder = orderService.getById(orderId);
            if (CommonEnum.WAIT_CHECK.getCode().equals(newOrder.getOrderStatus())) {
                newOrder.setOrderStatus(CommonEnum.FINISH.getCode());
                newOrder.setFinishTime(new Date());
                boolean save = orderService.updateById(newOrder);
                addIntegral(newOrder);
                if (save) {
                    return ResultBody.ok().message("订单签收成功");
                } else {
                    return ResultBody.error().message("订单签收失败");
                }
            }
            return ResultBody.error().message("订单签收失败");
        }
        return ResultBody.error().message("订单签收失败");
    }

    /**
     * 订单发货情况
     *
     * @param order 订单
     * @return 订单评价情况
     */
    @ApiOperation(value = "订单评价", notes = "订单评价")
    @PostMapping(value = "/appraiseOrder")
    public ResultBody appraiseOrder(@RequestBody Order order) {
        Order originOrder = orderService.getById(order.getOrderId());
        if (CommonEnum.FINISH.getCode().equals(originOrder.getOrderStatus())) {
            originOrder.setCommentLevel(order.getCommentLevel());
            originOrder.setCommentContent(order.getCommentContent());
            boolean save = orderService.updateById(originOrder);
            if (save) {
                return ResultBody.ok().message("订单评价成功");
            } else {
                return ResultBody.error().message("订单评价失败");
            }
        }
        return ResultBody.error().message("订单评价失败");
    }

    /**
     * 获取需要取消的订单，并自动过期（每十分钟执行一次）
     */
    @Scheduled(cron = "0 0/10 * * * ?")
    private void getCancelOrder() {
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getOrderStatus, CommonEnum.WAIT_PAY.getCode()).lt(Order::getCreateTime, DateUtil.yesterday());
        List<Order> orderList = orderService.list(orderWrapper);
        if (!orderList.isEmpty()) {
            orderList.forEach(e -> cancelOrder(e.getOrderId()));
        }
    }

    /**
     * 24小时取消订单
     *
     * @param orderId 订单Id
     */
    private void cancelOrder(Long orderId) {
        Order order = orderService.getById(orderId);
        if (order.getOrderStatus().equals(CommonEnum.WAIT_PAY.getCode())) {
            order.setOrderStatus(CommonEnum.CLOSE.getCode());
            orderService.updateById(order);
        }
    }

    /**
     * 增加积分
     *
     * @param order 订单信息
     */
    private void addIntegral(Order order) {
        LambdaQueryWrapper<UserDetail> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(UserDetail::getUserId, order.getUserId());
        UserDetail userDetail = userDetailService.getOne(userWrapper);
        Integer currentGetIntegral = order.getPaidIn().intValue();
        userDetail.setUserPoints(userDetail.getUserPoints() + currentGetIntegral);
        userDetail.setHistoryPoints(userDetail.getHistoryPoints() + currentGetIntegral);
        userDetailService.updateById(userDetail);
    }

}

